﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using BOSS.Framework.Search.Result;
using BOSS.Framework.Search.UrlBuilder;
using BOSS.Framework.Search.ValueProvider;

namespace BOSS.Framework.Search.Context
{
    /// <summary>
    /// 搜索上下文的标准实现类
    /// </summary>
    [Serializable]
    public class SearchContext : ISearchContext, IResultCache
    {
        /// <summary>
        /// 主关键字字段名
        /// </summary>
        public const string PRIMARY_FIELD = "pf";

        /// <summary>
        /// 仅允许使用一个排序条件
        /// </summary>
        public const bool DEFAULT_ONE_SORT_ONLY = true;

        /// <summary>
        /// 第一页的页序号
        /// </summary>
        public const int FIRST_PAGE_INDEX = 1;

        private IList<IFilterPart> m_filters;

        private IList<ISortPart> m_sorts;

        [NonSerialized]
        private ISearchResult m_result;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="urlBuilderFactory"></param>
        /// <param name="defaultValueProvider"></param>
        public SearchContext(string contentType, IUrlBuilderFactory urlBuilderFactory, IDefaultValueProvider defaultValueProvider)
            : this(contentType, DEFAULT_ONE_SORT_ONLY, urlBuilderFactory, defaultValueProvider)
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="contentType"></param>
        /// <param name="oneSortOnly"></param>
        /// <param name="urlBuilderFactory"></param>
        /// <param name="defaultValueProvider"></param>
        public SearchContext(string contentType, bool oneSortOnly, IUrlBuilderFactory urlBuilderFactory, IDefaultValueProvider defaultValueProvider)
        {
            this.ContentType = contentType;
            this.m_filters = new List<IFilterPart>();
            this.m_sorts = new List<ISortPart>();
            this.PageSize = 20;
            this.PageIndex = FIRST_PAGE_INDEX;
            this.OneSortOnly = oneSortOnly;
            this.UrlBuilderFactory = urlBuilderFactory ?? new SimpleUrlBuilderFactory();
            this.DefaultValueProvider = defaultValueProvider ?? new SimpleDefaultValueProvider();
            this.m_result = null;
        }

        #region ISearchContext Members

        /// <summary>
        /// 获取 内容类型
        /// </summary>
        public string ContentType { get; private set; }

        /// <summary>
        /// 获取 过滤参数部分的长度
        /// </summary>
        public int FilterCount
        {
            get { return this.m_filters.Count; }
        }

        /// <summary>
        /// 获取 过滤参数部分
        /// </summary>
        public IEnumerable<IFilterPart> Filters
        {
            get { return this.m_filters; }
        }

        /// <summary>
        /// 获取 是否只允许一个排序参数
        /// </summary>
        public bool OneSortOnly { get; private set; }

        /// <summary>
        /// 获取 排序参数部分的长度
        /// </summary>
        public int SortCount
        {
            get { return this.m_sorts.Count; }
        }

        /// <summary>
        /// 获取 排序参数部分
        /// </summary>
        public IEnumerable<ISortPart> Sorts
        {
            get { return this.m_sorts; }
        }

        /// <summary>
        /// 获取 分页大小
        /// </summary>
        public int PageSize { get; private set; }

        /// <summary>
        /// 获取 当前页序号，下标从 1 开始
        /// </summary>
        public int PageIndex { get; private set; }

        /// <summary>
        /// 获取 URL 构造器工厂
        /// </summary>
        public IUrlBuilderFactory UrlBuilderFactory { get; private set; }

        /// <summary>
        /// 获取 默认值提供器
        /// </summary>
        public IDefaultValueProvider DefaultValueProvider { get; private set; }

        /// <summary>
        /// 设置过滤部分
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        public void SetFilter(string fieldName, string value)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart existed = null;
            foreach (IFilterPart filter in this.m_filters)
            {
                if (string.Compare(filter.FieldName, fieldName, true) == 0)
                {
                    existed = filter;
                    break;
                }
            }

            if (IsDefaultValue(fieldName, value))
            {
                if (existed != null)
                {
                    this.m_filters.Remove(existed);
                    this.MarkDirty();
                }
                return;
            }

            TermStringFilterPart part = existed as TermStringFilterPart;
            if (part != null)
            {
                if (part.Value != value)
                {
                    part.Value = value;
                    this.MarkDirty();
                }
                return;
            }
            else if (existed != null)
            {
                this.m_filters.Remove(existed);
            }

            part = new TermStringFilterPart(fieldName, value);
            this.m_filters.Add(part);
            this.MarkDirty();
        }

        /// <summary>
        /// 设置过滤部分
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        public void SetFilter(string fieldName, decimal value)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart existed = null;
            foreach (IFilterPart filter in this.m_filters)
            {
                if (string.Compare(filter.FieldName, fieldName, true) == 0)
                {
                    existed = filter;
                    break;
                }
            }

            if (IsDefaultValue(fieldName, value))
            {
                if (existed != null)
                {
                    this.m_filters.Remove(existed);
                    this.MarkDirty();
                }
                return;
            }

            TermNumberFilterPart part = existed as TermNumberFilterPart;
            if (part != null)
            {
                if (part.Value != value)
                {
                    part.Value = value;
                    this.MarkDirty();
                }
                return;
            }
            else if (existed != null)
            {
                this.m_filters.Remove(existed);
            }

            part = new TermNumberFilterPart(fieldName, value);
            this.m_filters.Add(part);
            this.MarkDirty();
        }

        /// <summary>
        /// 设置过滤部分
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        public void SetFilter(string fieldName, int value)
        {
            this.SetFilter(fieldName, (decimal)value);
        }

        /// <summary>
        /// 设置过滤部分
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        public void SetFilter(string fieldName, bool value)
        {
            this.SetFilter(fieldName, value ? 1m : 0m);
        }

        /// <summary>
        /// 设置过滤部分
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="minValue"></param>
        /// <param name="includeMinValue"></param>
        /// <param name="maxValue"></param>
        /// <param name="includeMaxValue"></param>
        public void SetFilter(string fieldName, DateTime minValue, bool includeMinValue, DateTime maxValue, bool includeMaxValue)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart existed = null;
            foreach (IFilterPart filter in this.m_filters)
            {
                if (string.Compare(filter.FieldName, fieldName, true) == 0)
                {
                    existed = filter;
                    break;
                }
            }

            RangeDateFilterPart part = existed as RangeDateFilterPart;
            if (part != null)
            {
                if ((part.MinValue != minValue) || (part.IncludeMinValue != includeMinValue)
                    || (part.MaxValue != maxValue) || (part.IncludeMaxValue != includeMaxValue))
                {
                    part.MinValue = minValue;
                    part.IncludeMinValue = includeMinValue;
                    part.MaxValue = maxValue;
                    part.IncludeMaxValue = includeMaxValue;
                    this.MarkDirty();
                }
                return;
            }
            else if (existed != null)
            {
                this.m_filters.Remove(existed);
            }

            part = new RangeDateFilterPart(fieldName, minValue, includeMinValue, maxValue, includeMaxValue);
            this.m_filters.Add(part);
            this.MarkDirty();
        }

        /// <summary>
        /// 设置过滤部分
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="minValue"></param>
        /// <param name="includeMinValue"></param>
        /// <param name="maxValue"></param>
        /// <param name="includeMaxValue"></param>
        public void SetFilter(string fieldName, decimal minValue, bool includeMinValue, decimal maxValue, bool includeMaxValue)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart existed = null;
            foreach (IFilterPart filter in this.m_filters)
            {
                if (string.Compare(filter.FieldName, fieldName, true) == 0)
                {
                    existed = filter;
                    break;
                }
            }

            RangeNumberFilterPart part = existed as RangeNumberFilterPart;
            if (part != null)
            {
                if ((part.MinValue != minValue) || (part.IncludeMinValue != includeMinValue)
                    || (part.MaxValue != maxValue) || (part.IncludeMaxValue != includeMaxValue))
                {
                    part.MinValue = minValue;
                    part.IncludeMinValue = includeMinValue;
                    part.MaxValue = maxValue;
                    part.IncludeMaxValue = includeMaxValue;
                    this.MarkDirty();
                }
                return;
            }
            else if (existed != null)
            {
                this.m_filters.Remove(existed);
            }

            part = new RangeNumberFilterPart(fieldName, minValue, includeMinValue, maxValue, includeMaxValue);
            this.m_filters.Add(part);
            this.MarkDirty();
        }

        /// <summary>
        /// 设置过滤部分
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="minValue"></param>
        /// <param name="includeMinValue"></param>
        /// <param name="maxValue"></param>
        /// <param name="includeMaxValue"></param>
        public void SetFilter(string fieldName, int minValue, bool includeMinValue, int maxValue, bool includeMaxValue)
        {
            this.SetFilter(fieldName, (decimal)minValue, includeMinValue, (decimal)maxValue, includeMaxValue);
        }

        /// <summary>
        /// 移除过滤部份
        /// </summary>
        /// <param name="fieldName"></param>
        public void RemoveFilter(string fieldName)
        {
            fieldName = RetrieveFieldName(fieldName);

            foreach (IFilterPart filter in this.m_filters)
            {
                if (string.Compare(filter.FieldName, fieldName, true) == 0)
                {
                    this.m_filters.Remove(filter);
                    this.MarkDirty();
                    return;
                }
            }
        }

        /// <summary>
        /// 设置排序部分
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="descend"></param>
        public void SetSort(string fieldName, bool descend)
        {
            fieldName = RetrieveFieldName(fieldName);

            if (this.OneSortOnly)
            {
                this.m_sorts.Clear();
                this.m_sorts.Add(new SortPart(fieldName, descend));
            }
            else
            {
                ISortPart existed = null;
                foreach (ISortPart sort in this.m_sorts)
                {
                    if (string.Compare(sort.FieldName, fieldName, true) == 0)
                    {
                        existed = sort;
                        break;
                    }
                }

                if (existed != null)
                {
                    this.m_sorts.Remove(existed);
                    SortPart part = existed as SortPart;
                    if (part != null)
                    {
                        part.Descend = descend;
                    }
                    this.m_sorts.Insert(0, existed);
                }
                else
                {
                    this.m_sorts.Insert(0, new SortPart(fieldName, descend));
                }
            }
            this.MarkDirty();
        }

        /// <summary>
        /// 设置分页大小
        /// </summary>
        /// <param name="pageSize"></param>
        public void SetPageSize(int pageSize)
        {
            int newSize = Math.Max(1, pageSize);
            if (this.PageSize != newSize)
            {
                this.PageSize = newSize;
                this.MarkDirty();
            }
        }

        /// <summary>
        /// 设置页序号
        /// </summary>
        /// <param name="pageIndex"></param>
        public void SetPageIndex(int pageIndex)
        {
            int newIndex = Math.Max(FIRST_PAGE_INDEX, pageIndex);
            if (this.PageIndex != newIndex)
            {
                this.PageIndex = newIndex;
                this.MarkDirty();
            }
        }

        /// <summary>
        /// 构造 URL
        /// </summary>
        /// <returns></returns>
        public string BuildUrl()
        {
            return BuildUrl(this.m_filters, this.m_sorts, this.PageIndex);
        }

        /// <summary>
        /// 构造 URL
        /// </summary>
        /// <param name="urlBuilder"></param>
        /// <returns></returns>
        public string BuildUrl(IUrlBuilder urlBuilder)
        {
            return BuildUrl(urlBuilder, this.m_filters, this.m_sorts, this.PageIndex);
        }

        /// <summary>
        /// 根据新的过滤部分预取 URL，同时页序号被重置为初始值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string PrefetchNewFilterUrl(string fieldName, string value)
        {
            fieldName = RetrieveFieldName(fieldName);
            if (IsDefaultValue(fieldName, value))
            {
                return PrefetchNewFilterUrlImpl(fieldName, null);
            }
            else
            {
                IFilterPart filter = new TermStringFilterPart(fieldName, value);
                return PrefetchNewFilterUrlImpl(fieldName, filter);
            }
        }

        /// <summary>
        /// 根据新的过滤部分预取 URL，同时页序号被重置为初始值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string PrefetchNewFilterUrl(string fieldName, decimal value)
        {
            fieldName = RetrieveFieldName(fieldName);
            if (IsDefaultValue(fieldName, value))
            {
                return PrefetchNewFilterUrlImpl(fieldName, null);
            }
            else
            {
                IFilterPart filter = new TermNumberFilterPart(fieldName, value);
                return PrefetchNewFilterUrlImpl(fieldName, filter);
            }
        }

        /// <summary>
        /// 根据新的过滤部分预取 URL，同时页序号被重置为初始值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string PrefetchNewFilterUrl(string fieldName, int value)
        {
            return this.PrefetchNewFilterUrl(fieldName, (decimal)value);
        }

        /// <summary>
        /// 根据新的过滤部分预取 URL，同时页序号被重置为初始值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string PrefetchNewFilterUrl(string fieldName, bool value)
        {
            return PrefetchNewFilterUrl(fieldName, value ? 1m : 0m);
        }

        /// <summary>
        /// 根据新的过滤部分预取 URL，同时页序号被重置为初始值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="minValue"></param>
        /// <param name="includeMinValue"></param>
        /// <param name="maxValue"></param>
        /// <param name="includeMaxValue"></param>
        /// <returns></returns>
        public string PrefetchNewFilterUrl(string fieldName, DateTime minValue, bool includeMinValue, DateTime maxValue, bool includeMaxValue)
        {
            fieldName = RetrieveFieldName(fieldName);
            IFilterPart filter = new RangeDateFilterPart(fieldName, minValue, includeMinValue, maxValue, includeMaxValue);
            return PrefetchNewFilterUrlImpl(fieldName, filter);
        }

        /// <summary>
        /// 根据新的过滤部分预取 URL，同时页序号被重置为初始值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="minValue"></param>
        /// <param name="includeMinValue"></param>
        /// <param name="maxValue"></param>
        /// <param name="includeMaxValue"></param>
        /// <returns></returns>
        public string PrefetchNewFilterUrl(string fieldName, decimal minValue, bool includeMinValue, decimal maxValue, bool includeMaxValue)
        {
            fieldName = RetrieveFieldName(fieldName);
            IFilterPart filter = new RangeNumberFilterPart(fieldName, minValue, includeMinValue, maxValue, includeMaxValue);
            return PrefetchNewFilterUrlImpl(fieldName, filter);
        }

        /// <summary>
        /// 根据新的过滤部分预取 URL，同时页序号被重置为初始值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="minValue"></param>
        /// <param name="includeMinValue"></param>
        /// <param name="maxValue"></param>
        /// <param name="includeMaxValue"></param>
        /// <returns></returns>
        public string PrefetchNewFilterUrl(string fieldName, int minValue, bool includeMinValue, int maxValue, bool includeMaxValue)
        {
            return this.PrefetchNewFilterUrl(fieldName, (decimal)minValue, includeMinValue, (decimal)maxValue, includeMaxValue);
        }

        /// <summary>
        /// 根据新的排序部分预取 URL，同时页序号被重置为初始值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="descend"></param>
        /// <returns></returns>
        public string PrefetchNewSortUrl(string fieldName, bool descend)
        {
            fieldName = RetrieveFieldName(fieldName);
            ISortPart sortPart = new SortPart(fieldName, descend);

            if (this.OneSortOnly || this.m_sorts.Count == 0
                || ((this.m_sorts.Count == 1) && (string.Compare((this.m_sorts[0] as ISortPart).FieldName, fieldName, true) == 0)))
            {
                return BuildUrl(this.m_filters, new ISortPart[] { sortPart }, FIRST_PAGE_INDEX);
            }
            else
            {
                IList<ISortPart> sorts = new List<ISortPart>();
                sorts.Add(sortPart);
                foreach (ISortPart sort in this.m_sorts)
                {
                    if (string.Compare(sort.FieldName, fieldName, true) != 0)
                    {
                        sorts.Add(sort);
                    }
                }
                return BuildUrl(this.m_filters, sorts, FIRST_PAGE_INDEX);
            }
        }

        /// <summary>
        /// 根据新的排序部分预取 URL，同时页序号被重置为初始值。如果指定的字段为当前所使用的排序字段，则反转之
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="descendAsDefault"></param>
        /// <returns></returns>
        public string PrefetchNewToggleSortUrl(string fieldName, bool descendAsDefault)
        {
            fieldName = RetrieveFieldName(fieldName);

            ISortPart sortPart = null;
            if (this.m_sorts.Count == 0)
            {
                sortPart = new SortPart(fieldName, descendAsDefault);
            }
            else if (this.OneSortOnly)
            {
                ISortPart existed = this.m_sorts[0] as ISortPart;
                if (string.Compare(existed.FieldName, fieldName, true) == 0)
                {
                    sortPart = new SortPart(fieldName, !existed.Descend);
                }
                else
                {
                    sortPart = new SortPart(fieldName, descendAsDefault);
                }
            }
            else
            {
                ISortPart existed = null;
                IList<ISortPart> sorts = new List<ISortPart>();
                foreach (ISortPart sort in this.m_sorts)
                {
                    if (string.Compare(sort.FieldName, fieldName, true) != 0)
                    {
                        sorts.Add(sort);
                    }
                    else
                    {
                        existed = sort;
                    }
                }
                if (existed != null)
                {
                    sortPart = new SortPart(fieldName, !existed.Descend);
                }
                else
                {
                    sortPart = new SortPart(fieldName, descendAsDefault);
                }
                sorts.Insert(0, sortPart);
            }

            return BuildUrl(this.m_filters, new ISortPart[] { sortPart }, FIRST_PAGE_INDEX);
        }

        /// <summary>
        /// 根据新的页序号预取 URL
        /// </summary>
        /// <param name="absoluteIndex">是否使用绝对值</param>
        /// <param name="value">如果使用绝对值，则为新的页序号；否则为相对当前页的差值</param>
        /// <returns></returns>
        public string PrefetchNewPageIndexUrl(bool absoluteIndex, int value)
        {
            if (!absoluteIndex)
            {
                value = this.PageIndex + value;
            }

            return BuildUrl(this.m_filters, this.m_sorts, Math.Max(FIRST_PAGE_INDEX, value));
        }

        /// <summary>
        /// 获取过滤条件的布尔值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public bool? GetFilterTermValueAsBoolean(string fieldName)
        {
            fieldName = RetrieveFieldName(fieldName);
            IFilterPart filter = GetFilter(fieldName);
            if (filter == null)
            {
                int? fieldValue = this.DefaultValueProvider.GetDefaultValueAsInt32(this.ContentType, fieldName);

                if (fieldValue == null)
                {
                    return null;
                }
                else
                {
                    return fieldValue.Value != 0;
                }
            }

            TermStringFilterPart ts = filter as TermStringFilterPart;
            if (ts != null)
            {
                bool boolValue = false;
                if (bool.TryParse(ts.Value, out boolValue))
                {
                    return boolValue;
                }
            }

            TermNumberFilterPart tn = filter as TermNumberFilterPart;
            if (tn != null)
            {
                return tn.Value != 0;
            }

            return this.DefaultValueProvider.GetDefaultValueAsInt32(this.ContentType, fieldName).Value != 0;
        }

        /// <summary>
        /// 获取过滤条件的整数值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public decimal? GetFilterTermValueAsDecimal(string fieldName)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart filter = GetFilter(fieldName);
            if (filter == null)
            {
                return this.DefaultValueProvider.GetDefaultValueAsDecimal(this.ContentType, fieldName);
            }

            TermNumberFilterPart tn = filter as TermNumberFilterPart;
            if (tn != null)
            {
                return tn.Value;
            }

            TermStringFilterPart ts = filter as TermStringFilterPart;
            if (ts != null)
            {
                decimal decimalValue = 0;
                if (decimal.TryParse(ts.Value, out decimalValue))
                {
                    return decimalValue;
                }
            }

            return this.DefaultValueProvider.GetDefaultValueAsDecimal(this.ContentType, fieldName);
        }

        /// <summary>
        /// 获取过滤条件的整数值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public int? GetFilterTermValueAsInt32(string fieldName)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart filter = GetFilter(fieldName);
            if (filter == null)
            {
                return this.DefaultValueProvider.GetDefaultValueAsInt32(this.ContentType, fieldName);
            }

            TermNumberFilterPart tn = filter as TermNumberFilterPart;
            if (tn != null)
            {
                return Convert.ToInt32(tn.Value);
            }

            TermStringFilterPart ts = filter as TermStringFilterPart;
            if (ts != null)
            {
                int intValue = 0;
                if (int.TryParse(ts.Value, out intValue))
                {
                    return intValue;
                }
            }

            return this.DefaultValueProvider.GetDefaultValueAsInt32(this.ContentType, fieldName);
        }

        /// <summary>
        /// 获取过滤条件的字符串值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public string GetFilterTermValueAsString(string fieldName)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart filter = GetFilter(fieldName);
            if (filter == null)
            {
                return this.DefaultValueProvider.GetDefaultValueAsString(this.ContentType, fieldName);
            }

            TermNumberFilterPart tn = filter as TermNumberFilterPart;
            if (tn != null)
            {
                return tn.Value.ToString();
            }

            TermStringFilterPart ts = filter as TermStringFilterPart;
            if (ts != null)
            {
                return ts.Value;
            }

            return this.DefaultValueProvider.GetDefaultValueAsString(this.ContentType, fieldName);
        }

        /// <summary>
        /// 获取过滤条件的格式化后的字符串值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public string GetFilterTermValueAsString(string fieldName, string format)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart filter = GetFilter(fieldName);
            if (filter == null)
            {
                return this.DefaultValueProvider.GetDefaultValueAsString(this.ContentType, fieldName);
            }

            TermNumberFilterPart tn = filter as TermNumberFilterPart;
            if (tn != null)
            {
                return string.Format(format, tn.Value);
            }

            TermStringFilterPart ts = filter as TermStringFilterPart;
            if (ts != null)
            {
                return string.Format(format, ts.Value);
            }

            return this.DefaultValueProvider.GetDefaultValueAsString(this.ContentType, fieldName);
        }

        /// <summary>
        /// 获取范围过滤条件的最小整数值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public decimal? GetFilterRangeMinValueAsDecimal(string fieldName)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart filter = GetFilter(fieldName);
            if (filter == null)
            {
                return null;
            }

            RangeNumberFilterPart rn = filter as RangeNumberFilterPart;
            if (rn != null)
            {
                if (rn.MinValue == decimal.MinValue || rn.MinValue == int.MinValue)
                {
                    return null;
                }
                return rn.IncludeMinValue ? rn.MinValue : rn.MinValue + 1;
            }

            return null;
        }

        /// <summary>
        /// 获取范围过滤条件的最大整数值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public decimal? GetFilterRangeMaxValueAsDecimal(string fieldName)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart filter = GetFilter(fieldName);
            if (filter == null)
            {
                return null;
            }

            RangeNumberFilterPart rn = filter as RangeNumberFilterPart;
            if (rn != null)
            {
                if (rn.MaxValue == decimal.MaxValue || rn.MaxValue == int.MaxValue)
                {
                    return null;
                }
                return rn.IncludeMaxValue ? rn.MaxValue : rn.MaxValue - 1;
            }

            return null;
        }

        /// <summary>
        /// 获取范围过滤条件的最小整数值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public int? GetFilterRangeMinValueAsInt32(string fieldName)
        {
            decimal? decimalValue = this.GetFilterRangeMinValueAsDecimal(fieldName);
            if (decimalValue == null)
            {
                return null;
            }
            else
            {
                return (int)decimalValue.GetValueOrDefault();
            }
        }

        /// <summary>
        /// 获取范围过滤条件的最大整数值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public int? GetFilterRangeMaxValueAsInt32(string fieldName)
        {
            decimal? decimalValue = this.GetFilterRangeMaxValueAsDecimal(fieldName);
            if (decimalValue == null)
            {
                return null;
            }
            else
            {
                return (int)decimalValue.GetValueOrDefault();
            }
        }

        /// <summary>
        /// 获取范围过滤条件的最小日期值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public DateTime? GetFilterRangeMinValueAsDateTime(string fieldName)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart filter = GetFilter(fieldName);
            if (filter == null)
            {
                return null;
            }

            RangeDateFilterPart rd = filter as RangeDateFilterPart;
            if (rd != null)
            {
                if (rd.MinValue == DateTime.MinValue)
                {
                    return null;
                }
                return rd.IncludeMinValue ? rd.MinValue : rd.MinValue.AddDays(1);
            }

            return null;
        }

        /// <summary>
        /// 获取范围过滤条件的最大日期值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        public DateTime? GetFilterRangeMaxValueAsDateTime(string fieldName)
        {
            fieldName = RetrieveFieldName(fieldName);

            IFilterPart filter = GetFilter(fieldName);
            if (filter == null)
            {
                return null;
            }

            RangeDateFilterPart rd = filter as RangeDateFilterPart;
            if (rd != null)
            {
                if (rd.MaxValue == DateTime.MaxValue)
                {
                    return null;
                }
                return rd.IncludeMaxValue ? rd.MaxValue : rd.MaxValue.AddDays(-1);
            }

            return null;
        }

        #endregion

        #region IResultCache 成员

        /// <summary>
        /// 获取 相关查询结果
        /// </summary>
        public ISearchResult Result
        {
            get
            {
                return this.m_result;
            }
            set
            {
                this.m_result = value;
            }
        }

        #endregion

        /// <summary>
        /// 获取 / 设置 主关键字段
        /// </summary>
        internal string PrimaryField { get; set; }

        /// <summary>
        /// 设置过滤参数
        /// </summary>
        /// <param name="filter"></param>
        public void SetFilter(IFilterPart filter)
        {
            TermNumberFilterPart tn = filter as TermNumberFilterPart;
            if (tn != null)
            {
                this.SetFilter(tn.FieldName, tn.Value);
                return;
            }

            TermStringFilterPart ts = filter as TermStringFilterPart;
            if (ts != null)
            {
                this.SetFilter(ts.FieldName, ts.Value);
                return;
            }

            RangeNumberFilterPart rn = filter as RangeNumberFilterPart;
            if (rn != null)
            {
                this.SetFilter(rn.FieldName, rn.MinValue, rn.IncludeMinValue, rn.MaxValue, rn.IncludeMaxValue);
                return;
            }

            RangeDateFilterPart rd = filter as RangeDateFilterPart;
            if (rd != null)
            {
                this.SetFilter(rd.FieldName, rd.MinValue, rd.IncludeMinValue, rd.MaxValue, rd.IncludeMaxValue);
                return;
            }
        }

        /// <summary>
        /// 设置排序参数
        /// </summary>
        /// <param name="sortPart"></param>
        internal void SetSort(ISortPart sortPart)
        {
            this.SetSort(sortPart.FieldName, sortPart.Descend);
        }

        /// <summary>
        /// 标志搜索上下文在上次更新之后又有了变化
        /// </summary>
        private void MarkDirty()
        {
            this.m_result = null;
        }

        /// <summary>
        /// 获取字段名称
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        private string RetrieveFieldName(string fieldName)
        {
            if (string.Compare(SearchContext.PRIMARY_FIELD, fieldName, true) == 0)
            {
                if (this.PrimaryField != null)
                {
                    return this.PrimaryField;
                }
            }
            return fieldName;
        }

        /// <summary>
        /// 获取指定字段名称的过滤条件
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        private IFilterPart GetFilter(string fieldName)
        {
            foreach (IFilterPart query in this.m_filters)
            {
                if (string.Compare(query.FieldName, fieldName, true) == 0)
                {
                    return query;
                }
            }
            return null;
        }

        /// <summary>
        /// 给定的值是否为指定字段的缺省值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private bool IsDefaultValue(string fieldName, string value)
        {
            return this.DefaultValueProvider.IsDefaultValue(this.ContentType, fieldName, value);
        }

        /// <summary>
        /// 给定的值是否为指定字段的缺省值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private bool IsDefaultValue(string fieldName, decimal value)
        {
            return this.DefaultValueProvider.IsDefaultValue(this.ContentType, fieldName, value);
        }

        /// <summary>
        /// 给定的值是否为指定字段的缺省值
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private bool IsDefaultValue(string fieldName, int value)
        {
            return this.DefaultValueProvider.IsDefaultValue(this.ContentType, fieldName, value);
        }

        /// <summary>
        /// 根据新的过滤部分预取 URL
        /// </summary>
        /// <param name="fieldName"></param>
        /// <param name="newFilter"></param>
        /// <returns></returns>
        private string PrefetchNewFilterUrlImpl(string fieldName, IFilterPart newFilter)
        {
            if ((this.m_filters.Count == 0)
                || ((this.m_filters.Count == 1) && (string.Compare((this.m_filters[0] as IFilterPart).FieldName, fieldName, true) == 0)))
            {
                if (newFilter == null)
                {
                    return BuildUrl(new IFilterPart[] { }, this.m_sorts, FIRST_PAGE_INDEX);
                }
                else
                {
                    return BuildUrl(new IFilterPart[] { newFilter }, this.m_sorts, FIRST_PAGE_INDEX);
                }
            }
            else
            {
                IList<IFilterPart> filters = new List<IFilterPart>();
                foreach (IFilterPart filter in this.m_filters)
                {
                    if (string.Compare(filter.FieldName, fieldName, true) == 0)
                    {
                        if (newFilter != null)
                        {
                            filters.Add(newFilter);
                            newFilter = null;
                        }
                    }
                    else
                    {
                        filters.Add(filter);
                    }
                }
                if (newFilter != null)
                {
                    filters.Add(newFilter);
                }
                return BuildUrl(filters, this.m_sorts, FIRST_PAGE_INDEX);
            }
        }

        /// <summary>
        /// 创建 URL 的实现代码
        /// </summary>
        /// <param name="filters">IEnumerable&lt;IFilterPart&gt;</param>
        /// <param name="sorts">IEnumerable&lt;ISortPart&gt;</param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        private string BuildUrl(IEnumerable<IFilterPart> filters, IEnumerable<ISortPart> sorts, int pageIndex)
        {
            return BuildUrl(this.UrlBuilderFactory.CreateBuilder(), filters, sorts, pageIndex);
        }

        /// <summary>
        /// 创建 URL 的实现代码
        /// </summary>
        /// <param name="urlBuilder"></param>
        /// <param name="filters">IEnumerable&lt;IFilterPart&gt;</param>
        /// <param name="sorts">IEnumerable&lt;ISortPart&gt;</param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        private string BuildUrl(IUrlBuilder urlBuilder, IEnumerable<IFilterPart> filters, IEnumerable<ISortPart> sorts, int pageIndex)
        {
            urlBuilder.Initialize(this.ContentType);

            urlBuilder.BeginFilter();
            foreach (IFilterPart part in filters)
            {
                part.BuildUrl(urlBuilder);
            }
            urlBuilder.EndFilter();

            urlBuilder.BeginSort();
            foreach (ISortPart part in sorts)
            {
                part.BuildUrl(urlBuilder);
            }
            urlBuilder.EndSort();

            urlBuilder.SetPageSize(this.PageSize);

            return urlBuilder.GetUrl(pageIndex);
        }
    }
}
